package bqg

import (
	"fmt"
	"github.com/PuerkitoBio/goquery"
	"net/http"
	"os"
	"save-kindle/entity"
	"save-kindle/log"
	"save-kindle/source"
	"strings"
	"time"
)

type BqgSource struct {
	source.BookInfo
}

func NewBqgSource(webSite string) *BqgSource {
	return &BqgSource{source.BookInfo{
		WebSite: webSite,
	}}
}

func (book BqgSource) NewBook(bookId, bookName string) {
	book.BookId, book.BookName = bookId, bookName
}

func (book BqgSource) GetArticle() {
	// 获取目录
	catalog, _ := book.GetCatalog()

	file, err := os.OpenFile(fmt.Sprintf("%s.txt", book.BookName), os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)
	if err != nil {
		log.PrintErr(err.Error())
	}
	defer file.Close()

	file.WriteString("\n")

	for i, article := range catalog {
		log.Println(i, article)
		article, _ = book.GetArticleContent(article)

		writeFile(file, article)
		//break
	}
}

// GetCatalog 获取文章目录
func (book BqgSource) GetCatalog() ([]entity.Article, error) {
	bookUrl := fmt.Sprintf("https://www.biquger.com/biquge/%s/", book.BookId)
	request, _ := http.NewRequest("GET", bookUrl, nil)

	response, err := http.DefaultClient.Do(request)
	if err != nil {
		log.PrintErr(err.Error())
	}

	defer response.Body.Close()

	// 解析章节
	document, err := goquery.NewDocumentFromReader(response.Body)
	if err != nil {
		log.PrintErr(err.Error())
	}

	articles := make([]entity.Article, 0)

	document.Find("#list").Each(func(i int, selection *goquery.Selection) {
		selection.Find("dd").Each(func(ii int, ddTag *goquery.Selection) {
			attr, exists := ddTag.Find("a").Attr("href")
			if exists {
				article := entity.Article{
					ArticleUrl:  attr,
					ArticleName: ddTag.Text(),
				}
				// log.Println(article)
				articles = append(articles, article)
			}
		})
	})
	return articles, nil
}

// getArticleContent 获取文章内容
func (book BqgSource) GetArticleContent(article entity.Article) (entity.Article, error) {
retry:
	request, _ := http.NewRequest("GET", article.ArticleUrl, nil)
	response, err := http.DefaultClient.Do(request)
	if err != nil {
		log.PrintErr(err.Error())
	}
	defer response.Body.Close()

	if response.StatusCode != http.StatusOK {
		time.Sleep(1 * time.Second)
		log.PrintErr("retry", article)
		goto retry
	}

	document, err := goquery.NewDocumentFromReader(response.Body)
	if err != nil {
		log.PrintErr(err.Error())
	}
	document.Find("#booktext").Each(func(i int, selection *goquery.Selection) {
		html, _ := selection.Html()
		html = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(html, " ", ""), "<br/>", ""), "\n\n", "\n")

		// 去掉末尾的
		// <center>
		//  高速文字手打 <a href="https://www.biquger.com">笔趣阁</a> 捡个杀手做老婆章节列表<a href="/biquge/706/"> https://www.biquger.com/biquge/706/</a></center>
		index := strings.Index(html, "<center")
		if index > -1 {
			article.ArticleContent = html[:index]
		}
	})
	if article.ArticleContent == "" {
		// 暂停1s进行重试
		log.PrintErr("retry", article)
		time.Sleep(750 * time.Millisecond)
		goto retry
	}
	return article, nil
}

// writeFile 写入文件
func writeFile(file *os.File, v entity.Article) {
	file.WriteString(v.ArticleName)
	file.WriteString(v.ArticleContent + "\n\n")
}
